import datetime
import json
from urllib.parse import parse_qs

from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django_redis import get_redis_connection
from utils.encrypt import uid
from utils.alipay import AliPay


from web import models


def index(request):
    return render(request, 'index.html')


def price(request):
    policy_list = models.PricePolicy.objects.filter(category=2)
    return render(request, 'price.html', {'policy_list': policy_list})


def payment(request, policy_id):
    """支付页面"""
    # 1. 价格策略（套餐）policy_id
    policy_object = models.PricePolicy.objects.filter(id=policy_id, category=2).first()
    if not policy_object:
        return redirect('web:price')
    # 2. 要购买的数量
    number = request.GET.get('number', '')
    if not number or not number.isdecimal():
        return redirect('web:price')
    number = int(number)
    if number < 1:
        return redirect('web:price')
    # 3. 计算原价
    origin_price = number * policy_object.price
    # 4. 之前购买过套餐，扣除之前购买所使用的费用
    balance = 0
    _object = None
    if request.tracer.price_policy.category == 2:
        # 找到之前的订单,支付费用，开始-结束时间,计算剩余天数=计算可以抵扣的钱
        _object = models.Transaction.objects.filter(user=request.tracer.user, status=2).order_by('-id').first()
        total_timedelta = _object.end_datetime - _object.start_datetime
        balance_timedelta = _object.end_datetime - datetime.datetime.now()
        if total_timedelta.days == balance_timedelta.days:
            balance = _object.price / total_timedelta.days * (balance_timedelta.days - 1)
        else:
            balance = _object.price / total_timedelta.days * balance_timedelta.days

    if balance >= origin_price:
        return redirect('web:price')

    context = {
        'policy_id': policy_object.id,
        'number': number,
        'origin_price': origin_price,
        'balance': round(balance, 2),
        'total_price': origin_price - balance,
    }
    # 把数据存入到redis中，用于支付的时候进行二次校验
    conn = get_redis_connection()
    key = "payment_{}".format(request.tracer.user.mobile_phone)
    conn.set(key, json.dumps(context), ex=60 * 30)

    context['policy_object'] = policy_object
    context['transcation'] = _object
    return render(request, 'payment.html', context)


def pay(request):
    """生成订单&支付宝支付"""
    # 对用户提价的数据再次校验,从redis中提取数据
    conn = get_redis_connection()
    key = "payment_{}".format(request.tracer.user.mobile_phone)
    context_string = conn.get(key)
    if not context_string:
        return redirect('web:price')
    context = json.loads(context_string.decode('utf-8'))
    # 1.生成订单&交易记录(待支付)
    order_id = uid(request.tracer.user.mobile_phone)
    total_price = context['total_price']
    models.Transaction.objects.create(
        status=1,
        order=order_id,
        user=request.tracer.user,
        price_policy_id=context['policy_id'],
        count=context['number'],
        price=total_price,
    )
    # 2. 跳转到支付宝去支付
    # 2.1 生成支付宝链接
    alipay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH,
    )
    query_params=alipay.direct_pay(
        subject="Tracer 系统会员",
        out_trade_no=order_id,
        total_amount=total_price,
    )
    pay_url="{}?{}".format(settings.ALI_GATEWAY, query_params)
    return redirect(pay_url)
    # 2.2 跳转到这个链接

def pay_notify(request):
    alipay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH,
    )
    """支付成功之后触发的yrl"""
    if request.method == 'GET':
        # 只做调整，并判断是否支付成功，不做状态更新
        # 获取订单id，根据订单id做状态更新
        # 用支付宝公钥对支付宝返回的数据requets.get获取之后进行检查，通过之后才表示这是支付宝返还的接口。
        params = request.GET.dict()
        sign=params.pop('sign')
        status=alipay.verify(params,sign)
        if status:
            return HttpResponse('支付完成')
        return HttpResponse('支付失败')
    else:
        body_str=request.body.decode('utf-8')
        post_data=parse_qs(body_str)
        post_dict={}
        for k,v in post_data.items():
            post_dict[k]=v[0]
        sign=post_dict.pop('sign',None)
        status=alipay.verify(post_dict,sign)
        if status:
            current_datetime=datetime.datetime.now()
            out_trade_no=post_dict['out_trade_no']
            _object=models.Transaction.objects.filter(order=out_trade_no).first()
            _object.status=2
            _object.start_datetime=current_datetime
            _object.end_datetime=current_datetime+datetime.timedelta(days=365*_object.count)
            _object.save()
            return HttpResponse('success')
        return HttpResponse('error')